package com.jrx.anytxn.transaction.service.impl;

import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.exception.TxnRuntimeException;
import com.jrx.anytxn.common.uitl.*;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.ErrorMsgConstant;
import com.jrx.anytxn.param.dto.product.PrWaiveInterestTableRes;
import com.jrx.anytxn.param.entity.PrInterestTable;
import com.jrx.anytxn.param.entity.PrPenaltyRateTable;
import com.jrx.anytxn.param.entity.PrProductTable;
import com.jrx.anytxn.param.service.product.IInterestTableService;
import com.jrx.anytxn.param.service.product.IPrPenaltyRateTableService;
import com.jrx.anytxn.param.service.product.IPrWaiveInterestTableService;
import com.jrx.anytxn.param.service.product.IProductTableService;
import com.jrx.anytxn.transaction.bean.*;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.*;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmAccountMainInfoMapper;
import com.jrx.anytxn.transaction.service.*;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;

@Service
public class AccountServiceImpl implements IAccountService {
    private static final Logger logger = LoggerFactory.getLogger(AccountServiceImpl.class);

    @Autowired
    private IInterestTableService interestTableService;
    @Autowired
    private ISegmentService segmentService;
    @Autowired
    private ITlTransactionInfoService tlTransactionInfoService;
    @Autowired
    private IRepaymentPlanService repaymentPlanService;
    @Autowired
    private IProductTableService productTableService;
    @Autowired
    private IDealDelqService delqService;
    @Autowired
    private IGlInterfaceService glInterfaceService;
    @Autowired
    private IPrWaiveInterestTableService prWaiveInterestTableService;
    @Autowired
    private IPrPenaltyRateTableService penaltyRateTableService;
    @Resource
    private ExtAmAccountMainInfoMapper extAmAccountMainInfoMapper;


    /**
     * 累计账户抛账  抛出交易账户
     *
     * @param amLoanMainInfo
     * @param amInterestAccrualInfo
     * @return
     */
    @Override
    public CastAccountTransactionBean castInterestAccount(AmLoanMainInfo amLoanMainInfo, AmLoanAccountInfo amLoanAccountInfo,
                                                          AmInterestAccrualInfo amInterestAccrualInfo, Date businessDate, boolean batchFlag) throws TxnException {
        AmAccountMainInfo intrAcct = new AmAccountMainInfo();
        BeanMapping.copy(amLoanMainInfo, intrAcct);
        try {
            intrAcct.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }

        intrAcct.setPostingAmount(amInterestAccrualInfo.getAccrualTotalAccruInterest());//入账金额
        intrAcct.setCurrBalance(amInterestAccrualInfo.getAccrualTotalAccruInterest());//余额
        intrAcct.setRepayAmount(BigDecimal.ZERO);//已还金额
        intrAcct.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        intrAcct.setPaymentDueDate(amInterestAccrualInfo.getPaymentDueDate());//到期还款日
        intrAcct.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        intrAcct.setOriginalAccountId(amInterestAccrualInfo.getAccountId());
        intrAcct.setBillingTenor(amInterestAccrualInfo.getBillingTenor());
        intrAcct.setPostingDate(businessDate);

        intrAcct.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        intrAcct.setInterestStartDate(amInterestAccrualInfo.getAccrualStartDate());
        intrAcct.setAccountingPhase(amInterestAccrualInfo.getAccountingPhase());
        intrAcct.setNonAccrualsFlag(amInterestAccrualInfo.getNonAccrualsFlag());
        intrAcct.setLoanClassify(amLoanAccountInfo.getLoanClassify());
        intrAcct.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_1);
        intrAcct.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_1);
        intrAcct.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_0);
        intrAcct.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        intrAcct.setTaxAmt(amInterestAccrualInfo.getTaxAmt());//税金
        intrAcct.setLiabilityFlag(amInterestAccrualInfo.getLiabilityFlag());
        intrAcct.setActualDailyRate(amInterestAccrualInfo.getAccrualDailyRate());


        //添加代偿回购判断
        if (TransBizConstant.COMPENSATORY_FLAG_1.equals(amLoanAccountInfo.getCompensatoryFlag())) {
            intrAcct.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_1);//代偿标识
            intrAcct.setCompensatoryDays(TransBizConstant.ONE);//	代偿天数为1
        }

        String accuTxnCode = amInterestAccrualInfo.getTxnCode();
        String acctTxnCode = accuTxnCode.substring(0, 1) + (Integer.parseInt(accuTxnCode.substring(1)) - 10);
        intrAcct.setTxnCode(acctTxnCode);
        //利息
        if (TransBizConstant.INTEREST_ACCRUAL_TYPE_66.equals(amInterestAccrualInfo.getAccountType())) {
            intrAcct.setAccountType(TransBizConstant.ACCOUNT_TYPE_04);//账户类型
            intrAcct.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_04, amLoanMainInfo.getTenantId(),
                    amLoanMainInfo.getCustomerId()));
            //更新订单上的余额  上层需更新订单 将更新字段入库
            amLoanAccountInfo.setCurrBalance(amLoanAccountInfo.getCurrBalance().add(intrAcct.getPostingAmount()));
            amLoanAccountInfo.setInterestBalance(amLoanAccountInfo.getInterestBalance().add(intrAcct.getPostingAmount()));
            amLoanAccountInfo.setAccruedInterest(BigDecimalUtils.substract(amLoanAccountInfo.getAccruedInterest(), intrAcct.getPostingAmount()));
            intrAcct.setPaymentDueDate(amInterestAccrualInfo.getPaymentDueDate());//到期还款日

            intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
            //还款日当天日终直接抛成逾期
            if (businessDate.compareTo(amInterestAccrualInfo.getPaymentDueDate()) >= 0 && batchFlag) {
                intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_2);
            }
        } else if (TransBizConstant.INTEREST_ACCRUAL_TYPE_10.equals(amInterestAccrualInfo.getAccountType())) {//罚息
            intrAcct.setAccountType(TransBizConstant.ACCOUNT_TYPE_11);//账户类型
            intrAcct.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_11, amLoanMainInfo.getTenantId(),
                    amLoanMainInfo.getCustomerId()));
            //更新订单上的罚息余额
            amLoanAccountInfo.setPenaltyBalance(amLoanAccountInfo.getPenaltyBalance().add(intrAcct.getPostingAmount()));
            amLoanAccountInfo.setAccruedPenalty(BigDecimalUtils.substract(amLoanAccountInfo.getAccruedPenalty(), intrAcct.getPostingAmount()));
            intrAcct.setPaymentDueDate(amInterestAccrualInfo.getPaymentDueDate());//到期还款日
            intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_2);
        } else if (TransBizConstant.INTEREST_ACCRUAL_TYPE_20.equals(amInterestAccrualInfo.getAccountType())) {//复利
            intrAcct.setAccountType(TransBizConstant.ACCOUNT_TYPE_12);//账户类型  复利
            intrAcct.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_12, amLoanMainInfo.getTenantId(),
                    amLoanMainInfo.getCustomerId()));
            //更新订单上的复利余额
            amLoanAccountInfo.setCompoundBalance(amLoanAccountInfo.getCompoundBalance().add(intrAcct.getPostingAmount()));
            amLoanAccountInfo.setAccruedCompound(BigDecimalUtils.substract(amLoanAccountInfo.getAccruedCompound(), intrAcct.getPostingAmount()));
            intrAcct.setPaymentDueDate(amInterestAccrualInfo.getPaymentDueDate());//到期还款日
            intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_2);
        }

        intrAcct.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        intrAcct.setCreateTime(null);
        intrAcct.setUpdateTime(null);
        intrAcct.setUpdateBy(TransBizConstant.SYS_OPRATE);
        CastAccountTransactionBean castAccountTransactionBean = new CastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(intrAcct);

        //生成交易信息
        TlTransactionInfo tlTransactionInfo = tlTransactionInfoService.buildTlTransactionInfo(intrAcct,
                TransBizConstant.TRANSCATION_REVERSAL_FLAG_0);
        castAccountTransactionBean.setTlTransactionInfo(tlTransactionInfo);

        //生成Gl流水
        TlGlInterfaceInfo tlGlInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(intrAcct, intrAcct.getPostingAmount().subtract(amInterestAccrualInfo.getTaxAmt()),
                intrAcct.getTxnCode(), intrAcct.getAccountingPhase(), businessDate);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);

        //价税分离
        String tranCode = acctTxnCode.substring(0, 1) + (Integer.parseInt(acctTxnCode.substring(1)) + 3);
        TlGlInterfaceInfo taxTlGlInterfaceInfo = glInterfaceService.buildTaxTlGlInterfaceInfo(intrAcct, intrAcct.getPostingAmount(), intrAcct.getTaxAmt(), tranCode
                , intrAcct.getAccountingPhase(), businessDate);
        castAccountTransactionBean.addTlGlInterfaceInfo(taxTlGlInterfaceInfo);

        return castAccountTransactionBean;
    }

    /**
     * 累计账户抛账  抛出交易账户
     *
     * @param amLoanMainInfo
     * @param amInterestAccrualInfo
     * @return
     */
    @Override
    public CastAccountTransactionBean castWaiveInterestAccount(AmLoanMainInfo amLoanMainInfo, AmLoanAccountInfo amLoanAccountInfo,
                                                               AmInterestAccrualInfo amInterestAccrualInfo, Date businessDate) throws TxnException {
        AmAccountMainInfo intrAcct = new AmAccountMainInfo();
        BeanMapping.copy(amLoanMainInfo, intrAcct);
        try {
            intrAcct.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }

        intrAcct.setPostingAmount(amInterestAccrualInfo.getAccrualTotalAccruInterest());//入账金额
        intrAcct.setCurrBalance(amInterestAccrualInfo.getAccrualTotalAccruInterest());//余额
        intrAcct.setRepayAmount(BigDecimal.ZERO);//已还金额
        intrAcct.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        intrAcct.setPaymentDueDate(amInterestAccrualInfo.getPaymentDueDate());//到期还款日
        intrAcct.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        intrAcct.setOriginalAccountId(amInterestAccrualInfo.getAccountId());
        intrAcct.setBillingTenor(amInterestAccrualInfo.getBillingTenor());
        intrAcct.setPostingDate(businessDate);

        intrAcct.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        intrAcct.setInterestStartDate(amInterestAccrualInfo.getAccrualStartDate());
        intrAcct.setAccountingPhase(amInterestAccrualInfo.getAccountingPhase());
        intrAcct.setNonAccrualsFlag(amInterestAccrualInfo.getNonAccrualsFlag());
        intrAcct.setLoanClassify(amLoanAccountInfo.getLoanClassify());
        intrAcct.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_1);
        intrAcct.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_1);
        intrAcct.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_0);
        intrAcct.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        intrAcct.setTaxAmt(amInterestAccrualInfo.getTaxAmt());//税金
        intrAcct.setLiabilityFlag(amInterestAccrualInfo.getLiabilityFlag());

        //利息
        intrAcct.setAccountType(TransBizConstant.ACCOUNT_TYPE_17);//账户类型
        intrAcct.setTxnCode(TransBizConstant.TXN_CODE_INST_WAIVE_INTR);
        intrAcct.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_17, amLoanMainInfo.getTenantId(),
                amLoanMainInfo.getCustomerId()));
        intrAcct.setPaymentDueDate(amInterestAccrualInfo.getPaymentDueDate());//到期还款日
        intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);


        intrAcct.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        intrAcct.setCreateTime(null);
        intrAcct.setUpdateTime(null);
        intrAcct.setUpdateBy(TransBizConstant.SYS_OPRATE);
        CastAccountTransactionBean castAccountTransactionBean = new CastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(intrAcct);

        //生成交易信息
        TlTransactionInfo tlTransactionInfo = tlTransactionInfoService.buildTlTransactionInfo(intrAcct,
                TransBizConstant.TRANSCATION_REVERSAL_FLAG_0);
        castAccountTransactionBean.setTlTransactionInfo(tlTransactionInfo);

        //生成Gl流水
        TlGlInterfaceInfo tlGlInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(intrAcct, intrAcct.getPostingAmount().subtract(amInterestAccrualInfo.getTaxAmt()),
                intrAcct.getTxnCode(), intrAcct.getAccountingPhase(), businessDate);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);

        //价税分离
        TlGlInterfaceInfo taxTlGlInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(intrAcct, amInterestAccrualInfo.getTaxAmt(), TransBizConstant.TXN_CODE_INST_WAIVE_INTR_TAX
                , intrAcct.getAccountingPhase(), businessDate);
        castAccountTransactionBean.addTlGlInterfaceInfo(taxTlGlInterfaceInfo);

        return castAccountTransactionBean;
    }

    /**
     * 根据原累计账户生成表外累计账户
     *
     * @param accuAcct
     * @param bussinessDate
     * @return
     * @throws TxnBizException
     */
    @Override
    public AmInterestAccrualInfo castNonInterestAccrualAccount(AmInterestAccrualInfo accuAcct, Date bussinessDate) throws TxnBizException {
        AmInterestAccrualInfo nonAccuAcct = new AmInterestAccrualInfo();
        BeanMapping.copy(accuAcct, nonAccuAcct);
        try {
            nonAccuAcct.setId(segmentService.getId(TransBizConstant.AM_INTEREST_ACCRUAL_INFO_ID));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }

        String txnCode = accuAcct.getTxnCode().replaceFirst("5", "9");
        nonAccuAcct.setTxnCode(txnCode);
        nonAccuAcct.setAccountId(getAccountId(accuAcct.getAccountType(),
                accuAcct.getTenantId(), accuAcct.getCustomerId()));//账户ID
        //表外罚息起息日特殊处理如果在宽限期之内则取原来的起息日，否则为当前业务日期
        Date startDate = bussinessDate.compareTo(accuAcct.getAccrualStartDate()) >= 0 ? bussinessDate : accuAcct.getAccrualStartDate();
        nonAccuAcct.setAccrualStartDate(startDate);//交易起息日期
        nonAccuAcct.setAccrualTotalAccruInterest(BigDecimal.ZERO);//已累计总利息
        nonAccuAcct.setAccrualTotalAccruDays(TransBizConstant.ZERO);//已累计总天数
        if (TransBizConstant.INTEREST_ACCRUAL_TYPE_66.equals(accuAcct.getAccountType())) {
            nonAccuAcct.setMaxInterest(accuAcct.getMaxInterest().subtract(accuAcct.getAccrualTotalAccruInterest()));//最大利息金额
        } else {
            nonAccuAcct.setMaxInterest(BigDecimal.ZERO);//最大利息金额
        }
        nonAccuAcct.setTaxAmt(BigDecimal.ZERO);
        nonAccuAcct.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        nonAccuAcct.setCreateTime(null);
        nonAccuAcct.setUpdateTime(null);
        return nonAccuAcct;
    }


    /**
     * 抛账  抛出本金账户
     *
     * @param amLoanMainInfo      订单
     * @param amRepaymentPlanInfo 抛账期次还款计划
     * @param businessDate        业务日期
     * @return
     */
    @Override
    public CastAccountTransactionBean castPrincipalAccount(AmLoanMainInfo amLoanMainInfo, AmLoanAccountInfo amLoanAccountInfo, AmRepaymentPlanInfo amRepaymentPlanInfo, DelqParamBean delqParamBean, Date businessDate) throws TxnException {
        AmAccountMainInfo amAccountMainInfo = new AmAccountMainInfo();
        BeanMapping.copy(amLoanMainInfo, amAccountMainInfo);
        try {
            amAccountMainInfo.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_ID));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        amAccountMainInfo.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_06, amAccountMainInfo.getTenantId()
                , amLoanMainInfo.getCustomerId()));//账户ID
        amAccountMainInfo.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        amAccountMainInfo.setAccountType(TransBizConstant.ACCOUNT_TYPE_06);//账户类型
        amAccountMainInfo.setTxnCode(TransBizConstant.TXN_CODE_INST);//交易码
        amAccountMainInfo.setBillingTenor(amRepaymentPlanInfo.getBillingTenor());//第几期	　
        amAccountMainInfo.setPostingAmount(amRepaymentPlanInfo.getPrincipalAmount());//入账金额
        amAccountMainInfo.setPostingDate(businessDate);//入账时间
        amAccountMainInfo.setRepayAmount(BigDecimal.ZERO);//已还金额
        amAccountMainInfo.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        amAccountMainInfo.setCurrBalance(amRepaymentPlanInfo.getPrincipalAmount());//余额
        amAccountMainInfo.setInterestStartDate(businessDate);//交易起息日
        amAccountMainInfo.setPaymentDueDate(amRepaymentPlanInfo.getPaymentDueDate());//到期还款日
        amAccountMainInfo.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        amAccountMainInfo.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        amAccountMainInfo.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_1);
        amAccountMainInfo.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_1);
        amAccountMainInfo.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_0);
        amAccountMainInfo.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        amAccountMainInfo.setLiabilityFlag(amRepaymentPlanInfo.getLiabilityFlag());
        amAccountMainInfo.setTaxAmt(BigDecimal.ZERO);
        amAccountMainInfo.setActualDailyRate(amRepaymentPlanInfo.getActualDailyRate());
        amAccountMainInfo.setCreateTime(null);
        amAccountMainInfo.setUpdateTime(null);
        amAccountMainInfo.setUpdateBy(TransBizConstant.SYS_OPRATE);
        if (TransBizConstant.COMPENSATORY_FLAG_1.equals(amLoanAccountInfo.getCompensatoryFlag())) {
            amAccountMainInfo.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_1);
            amAccountMainInfo.setCompensatoryDays(1);
        }
        //会计标志
        amAccountMainInfo.setAccountingPhase(amLoanAccountInfo.getAccountingPhase());
        //应计/非应计
        this.transNonAccrualsFlag(delqParamBean, amAccountMainInfo, amLoanAccountInfo);
        //五级分类
        amAccountMainInfo.setLoanClassify(amLoanAccountInfo.getLoanClassify());

        //更新订单上的余额  上层需更新订单 将更新字段入库
        amLoanAccountInfo.setCurrBalance(amLoanAccountInfo.getCurrBalance().add(amAccountMainInfo.getPostingAmount()));
        amLoanAccountInfo.setPrincipalBalance(amLoanAccountInfo.getPrincipalBalance().add(amAccountMainInfo.getPostingAmount()));

        //生成交易信息
        TlTransactionInfo tlTransactionInfo = tlTransactionInfoService.buildTlTransactionInfo(amAccountMainInfo,
                TransBizConstant.TRANSCATION_REVERSAL_FLAG_0);
        //生成Gl流水
        TlGlInterfaceInfo tlGlInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(amAccountMainInfo, amAccountMainInfo.getPostingAmount(),
                amAccountMainInfo.getTxnCode(), amAccountMainInfo.getAccountingPhase(), businessDate);
        CastAccountTransactionBean castAccountTransactionBean = new CastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(amAccountMainInfo);
        castAccountTransactionBean.setTlTransactionInfo(tlTransactionInfo);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);
        return castAccountTransactionBean;
    }

    /**
     * 交易账户应计转非应计
     *
     * @param delqParamBean
     * @param amAccountMainInfo
     * @param amLoanAccountInfo
     */
    private void transNonAccrualsFlag(DelqParamBean delqParamBean, AmAccountMainInfo amAccountMainInfo, AmLoanAccountInfo amLoanAccountInfo) {
        DelqNonAccrualBean delqNonAccrualBean = delqParamBean.getDelqNonAccrualBeanMap().get(amAccountMainInfo.getAccountType());
        //不转列 或者 转列方式为当期金额转列法
        if (TransBizConstant.TRANSFER_FLAG_0.equals(delqNonAccrualBean.getNonAccrualFlag())
                || TransBizConstant.TRANSFER_METHOD_3.equals(delqNonAccrualBean.getTransferMethod())) {
            amAccountMainInfo.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
            return;
        }
        amAccountMainInfo.setNonAccrualsFlag(amLoanAccountInfo.getNonAccrualsFlag());
    }

    /**
     * 抛账  抛出利息累计账户
     *
     * @param amRepaymentPlanInfo 当期还款计划
     * @param amAccountMainInfo   当期本金账户
     * @param accrualBaseAmount   计息基础金额
     * @return
     */
    @Override
    public AmInterestAccrualInfo castInterestAccrualAccount(AmRepaymentPlanInfo amRepaymentPlanInfo, AmAccountMainInfo amAccountMainInfo, AmLoanAccountInfo amLoanAccountInfo,
                                                            AmLoanMainInfo amLoanMainInfo, BigDecimal accrualBaseAmount, DelqParamBean delqParamBean) throws TxnBizException {
        if (BigDecimal.ZERO.compareTo(amRepaymentPlanInfo.getInterestAmount()) >= 0) {
            return null;
        }

        AmInterestAccrualInfo amInterestAccrualInfo = new AmInterestAccrualInfo();
        BeanMapping.copy(amAccountMainInfo, amInterestAccrualInfo);
        try {
            amInterestAccrualInfo.setId(segmentService.getId(TransBizConstant.AM_INTEREST_ACCRUAL_INFO_ID));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        amInterestAccrualInfo.setAccountId(getAccountId(TransBizConstant.INTEREST_ACCRUAL_TYPE_66,
                amAccountMainInfo.getTenantId(), amAccountMainInfo.getCustomerId()));//账户ID
        amInterestAccrualInfo.setAccountStatus(TransBizConstant.INTEREST_ACCRUAL_STATUS_1);//状态
        amInterestAccrualInfo.setAccountType(TransBizConstant.INTEREST_ACCRUAL_TYPE_66);//类型 利息累计账户
        amInterestAccrualInfo.setAccrualBaseAmount(accrualBaseAmount);//计息金额
        amInterestAccrualInfo.setAccrualStartDate(amRepaymentPlanInfo.getIntrStartDate());//交易起息日期
        amInterestAccrualInfo.setAccrualTotalAccruInterest(BigDecimal.ZERO);//已累计总利息
        amInterestAccrualInfo.setAccrualTotalAccruDays(TransBizConstant.ZERO);//已累计总天数
        amInterestAccrualInfo.setAccrualDailyRate(amRepaymentPlanInfo.getActualDailyRate());//实际日利率
        amInterestAccrualInfo.setAccrualNewFromDate(DateUtils.addDay(amRepaymentPlanInfo.getIntrStartDate(), -1));//累计利息开始日期
        amInterestAccrualInfo.setStopAccrualFlag(TransBizConstant.STOP_ACCRU_FLAG_0);//停止累计息标志	0 = 正常计息  1 = 停止计息
        amInterestAccrualInfo.setMaxInterest(amRepaymentPlanInfo.getInterestAmount());//最大利息金额
        amInterestAccrualInfo.setProfitShared(TransBizConstant.NO_FLAG);//是否已经分润	0 = 未分润 1 = 已分润  默认为0，未分润	初始固定值：0
        amInterestAccrualInfo.setBalTransferFlag(TransBizConstant.NO_FLAG);//债权转移标识
        amInterestAccrualInfo.setCompensatoryFlag(TransBizConstant.NO_FLAG);//代偿标识
        amInterestAccrualInfo.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);//	记录版本号	初始固定值：1
        amInterestAccrualInfo.setUpdateBy(TransBizConstant.SYS_OPRATE);
        amInterestAccrualInfo.setTaxAmt(BigDecimal.ZERO);
        amInterestAccrualInfo.setLiabilityFlag(amRepaymentPlanInfo.getLiabilityFlag());
        amInterestAccrualInfo.setProvisionalAccrualInterest(BigDecimal.ZERO);
        amInterestAccrualInfo.setProvisionalTaxAmt(BigDecimal.ZERO);
        amInterestAccrualInfo.setCreateTime(null);
        amInterestAccrualInfo.setUpdateTime(null);

        amInterestAccrualInfo.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);//会计状态
        //应计/非应计
        this.transNonAccrualsFlag(delqParamBean, amInterestAccrualInfo, amLoanAccountInfo);
        //五级分类
        amInterestAccrualInfo.setLoanClassify(amLoanAccountInfo.getLoanClassify());

        if (TransBizConstant.NON_ACCRUALS_FLA_0.equals(amInterestAccrualInfo.getNonAccrualsFlag())) {
            amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_INST_INTR_ACCU);
        } else {
            amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_INST_INTR_NONACCRUAL_ACCU);
        }
        return amInterestAccrualInfo;
    }

    /**
     * 抛账  抛出贴息累计账户
     *
     * @param amWaiveRepaymentPlanInfo 当期本金账户
     * @param accrualBaseAmount        计息基础金额
     * @return
     */
    @Override
    public AmInterestAccrualInfo castWaiveInterestAccrualAccount(AmWaiveRepaymentPlanInfo amWaiveRepaymentPlanInfo, AmLoanAccountInfo amLoanAccountInfo,
                                                                 AmLoanMainInfo amLoanMainInfo, BigDecimal accrualBaseAmount, DelqParamBean delqParamBean) throws TxnBizException {
        if (BigDecimal.ZERO.compareTo(amWaiveRepaymentPlanInfo.getInterestAmount()) >= 0) {
            return null;
        }

        AmInterestAccrualInfo amInterestAccrualInfo = new AmInterestAccrualInfo();
        BeanMapping.copy(amLoanAccountInfo, amInterestAccrualInfo);
        try {
            amInterestAccrualInfo.setId(segmentService.getId(TransBizConstant.AM_INTEREST_ACCRUAL_INFO_ID));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        amInterestAccrualInfo.setAccountId(getAccountId(TransBizConstant.INTEREST_ACCRUAL_TYPE_70,
                amLoanAccountInfo.getTenantId(), amLoanAccountInfo.getCustomerId()));//账户ID
        amInterestAccrualInfo.setAccountStatus(TransBizConstant.INTEREST_ACCRUAL_STATUS_1);//状态
        amInterestAccrualInfo.setAccountType(TransBizConstant.INTEREST_ACCRUAL_TYPE_70);//类型 利息累计账户
        amInterestAccrualInfo.setAccrualBaseAmount(accrualBaseAmount);//计息金额
        amInterestAccrualInfo.setAccrualStartDate(amWaiveRepaymentPlanInfo.getIntrStartDate());//交易起息日期
        amInterestAccrualInfo.setAccrualTotalAccruInterest(BigDecimal.ZERO);//已累计总利息
        amInterestAccrualInfo.setAccrualTotalAccruDays(TransBizConstant.ZERO);//已累计总天数
        if (TransBizConstant.WAIVE_TYPE_1.equals(amLoanMainInfo.getWaiveType())) {
            amInterestAccrualInfo.setInterestTableId(amLoanMainInfo.getWaiveInterestId());
        } else {
            amInterestAccrualInfo.setInterestTableId(amLoanMainInfo.getInterestTableId());
        }
        amInterestAccrualInfo.setAccrualDailyRate(amWaiveRepaymentPlanInfo.getActualDailyRate());//实际日利率
        amInterestAccrualInfo.setAccrualNewFromDate(DateUtils.addDay(amWaiveRepaymentPlanInfo.getIntrStartDate(), -1));//累计利息开始日期
        amInterestAccrualInfo.setStopAccrualFlag(TransBizConstant.STOP_ACCRU_FLAG_0);//停止累计息标志	0 = 正常计息  1 = 停止计息
        amInterestAccrualInfo.setMaxInterest(amWaiveRepaymentPlanInfo.getInterestAmount());//最大利息金额
        amInterestAccrualInfo.setProfitShared(TransBizConstant.NO_FLAG);//是否已经分润	0 = 未分润 1 = 已分润  默认为0，未分润	初始固定值：0
        amInterestAccrualInfo.setBalTransferFlag(TransBizConstant.NO_FLAG);//债权转移标识
        amInterestAccrualInfo.setCompensatoryFlag(TransBizConstant.NO_FLAG);//代偿标识
        amInterestAccrualInfo.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);//	记录版本号	初始固定值：1
        amInterestAccrualInfo.setUpdateBy(TransBizConstant.SYS_OPRATE);
        amInterestAccrualInfo.setTaxAmt(BigDecimal.ZERO);
        amInterestAccrualInfo.setCreateTime(null);
        amInterestAccrualInfo.setUpdateTime(null);
        amInterestAccrualInfo.setLiabilityFlag(amWaiveRepaymentPlanInfo.getLiabilityFlag());
        amInterestAccrualInfo.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);//会计状态
        amInterestAccrualInfo.setLoanClassify(amLoanAccountInfo.getLoanClassify());
        amInterestAccrualInfo.setBillingTenor(amWaiveRepaymentPlanInfo.getBillingTenor());
        amInterestAccrualInfo.setPenaltyTableId("");
        amInterestAccrualInfo.setPaymentDueDate(amWaiveRepaymentPlanInfo.getPaymentDueDate());
        amInterestAccrualInfo.setTotalTenor(amLoanMainInfo.getTotalTenor());
        amInterestAccrualInfo.setTotalDays(amLoanMainInfo.getTotalDays());
        amInterestAccrualInfo.setJointLoanFlag(amLoanMainInfo.getJointLoanFlag());
        amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_INST_WAIVE_INTR_ACCU);
        return amInterestAccrualInfo;
    }

    /**
     * 累计账户应计转非应计
     *
     * @param delqParamBean
     * @param amInterestAccrualInfo
     * @param amLoanAccountInfo
     */
    private void transNonAccrualsFlag(DelqParamBean delqParamBean, AmInterestAccrualInfo amInterestAccrualInfo, AmLoanAccountInfo amLoanAccountInfo) {
        DelqNonAccrualBean delqNonAccrualBean = delqParamBean.getDelqNonAccrualBeanMap().get(amInterestAccrualInfo.getAccountType());
        //不转列 或者 转列方式为当期金额转列法
        if (TransBizConstant.TRANSFER_FLAG_0.equals(delqNonAccrualBean.getNonAccrualFlag())
                || TransBizConstant.TRANSFER_METHOD_3.equals(delqNonAccrualBean.getTransferMethod())) {
            amInterestAccrualInfo.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
            return;
        }
        amInterestAccrualInfo.setNonAccrualsFlag(amLoanAccountInfo.getNonAccrualsFlag());
    }

    /**
     * 抛出罚息、复利累计账户
     *
     * @param amRepaymentPlanInfo
     * @param amLoanMainInfo
     * @param penaltyRateTable
     * @return
     * @throws TxnBizException
     */
    @Override
    public List<AmInterestAccrualInfo> castPenAndComAccrualAccount(AmRepaymentPlanInfo amRepaymentPlanInfo, AmLoanMainInfo amLoanMainInfo, AmLoanAccountInfo amLoanAccountInfo,
                                                                   PrPenaltyRateTable penaltyRateTable, DelqParamBean delqParamBean, Date intrBeginDate, Date businessDate) throws TxnBizException {
        List<AmInterestAccrualInfo> accountList = new ArrayList<>();
        PrProductTable prProductTable = productTableService.findProByProIdAndOrgId(amLoanMainInfo.getProductId(), amLoanMainInfo.getOrganizationId(), amLoanMainInfo.getTenantId());

        //计息基础
        String accrualBasic = penaltyRateTable.getAccrualBasic();

        //本金罚息计息基础
        BigDecimal accrualBaseAmount = amRepaymentPlanInfo.getPrincipalAmount().subtract(amRepaymentPlanInfo.getRepayPrincipal());

        //生成本金罚息累计账户
        AmInterestAccrualInfo penaltyAccrualInfo = generatePenOrComAccrualInfo(TransBizConstant.INTEREST_ACCRUAL_TYPE_10, amLoanMainInfo, amLoanAccountInfo,
                amRepaymentPlanInfo, prProductTable, penaltyRateTable, accrualBaseAmount, delqParamBean, intrBeginDate, businessDate);
        if (penaltyAccrualInfo != null) {
            accountList.add(penaltyAccrualInfo);
        }
        //1:逾期本金+利息（复利）
        if (TransBizConstant.PENALTY_ACCRUAL_BASIC_1.equals(accrualBasic)) {
            //复利计息基础
            BigDecimal comAccrualBaseAmount = amRepaymentPlanInfo.getInterestAmount().subtract(amRepaymentPlanInfo.getRepayInterest());

            if (TransBizConstant.YES_FLAG.equals(penaltyRateTable.getCastPenaltyPerMonth()) &&
                    TransBizConstant.YES_FLAG.equals(penaltyRateTable.getPenaltyAccrualCompound())) {
                //按照期次获取罚息交易账户
                List<AmAccountMainInfo> accountMainInfoList = extAmAccountMainInfoMapper.selectByLoanIdAndTypeAndCustomerIdAndBillingTenorAndStatusIn(amRepaymentPlanInfo.getLoanId(), TransBizConstant.ACCOUNT_TYPE_11, amRepaymentPlanInfo.getCustomerId(),
                        amRepaymentPlanInfo.getBillingTenor(), Arrays.asList(TransBizConstant.ACCOUNT_STATUS_1, TransBizConstant.ACCOUNT_STATUS_2), null, amRepaymentPlanInfo.getTenantId());
                if (CollectionUtils.isNotEmpty(accountMainInfoList)) {
                    for (AmAccountMainInfo accountMainInfo : accountMainInfoList) {
                        if (accountMainInfo.getPaymentDueDate().compareTo(businessDate) <= 0) {
                            comAccrualBaseAmount = comAccrualBaseAmount.add(accountMainInfo.getCurrBalance());
                        }
                    }
                }
            }

            if (TransBizConstant.YES_FLAG.equals(penaltyRateTable.getCastPenaltyPerMonth()) &&
                    TransBizConstant.YES_FLAG.equals(penaltyRateTable.getCompoundAccrualCompound())) {
                //查询当期对应的复利交易账户
                List<AmAccountMainInfo> accountMainInfoList = extAmAccountMainInfoMapper.selectByLoanIdAndTypeAndCustomerIdAndBillingTenorAndStatusIn(amRepaymentPlanInfo.getLoanId(), TransBizConstant.ACCOUNT_TYPE_12, amRepaymentPlanInfo.getCustomerId(),
                        amRepaymentPlanInfo.getBillingTenor(), Arrays.asList(TransBizConstant.ACCOUNT_STATUS_1, TransBizConstant.ACCOUNT_STATUS_2), null, amRepaymentPlanInfo.getTenantId());
                if (CollectionUtils.isNotEmpty(accountMainInfoList)) {
                    for (AmAccountMainInfo accountMainInfo : accountMainInfoList) {
                        if (accountMainInfo.getPaymentDueDate().compareTo(businessDate) <= 0) {
                            comAccrualBaseAmount = comAccrualBaseAmount.add(accountMainInfo.getCurrBalance());
                        }
                    }
                }
            }

            if (comAccrualBaseAmount.compareTo(BigDecimal.ZERO) > 0) {
                //复利累计账户
                AmInterestAccrualInfo comAccrualInfo = generatePenOrComAccrualInfo(TransBizConstant.INTEREST_ACCRUAL_TYPE_20, amLoanMainInfo, amLoanAccountInfo,
                        amRepaymentPlanInfo, prProductTable, penaltyRateTable, comAccrualBaseAmount, delqParamBean, intrBeginDate, businessDate);
                if (comAccrualInfo != null) {
                    accountList.add(comAccrualInfo);
                }
            }
        }
        return accountList;
    }

    /**
     * 组装罚息/复利累计账户
     *
     * @param accountType
     * @param amLoanMainInfo
     * @param amRepaymentPlanInfo
     * @param accrualBaseAmount
     * @return
     * @throws TxnBizException
     */
    private AmInterestAccrualInfo generatePenOrComAccrualInfo(String accountType, AmLoanMainInfo amLoanMainInfo, AmLoanAccountInfo amLoanAccountInfo,
                                                              AmRepaymentPlanInfo amRepaymentPlanInfo, PrProductTable prProductTable,
                                                              PrPenaltyRateTable penaltyRateTable, BigDecimal accrualBaseAmount,
                                                              DelqParamBean delqParamBean, Date intrBeginDate, Date businessDate) throws TxnBizException {
        //起息日
        String valueDate = penaltyRateTable.getValueDate();
        Integer graceDays = prProductTable.getGraceDays();
        //按订单计算 订单级宽限期，若往期处于逾期状态，则当期没有宽限期
        if (TransBizConstant.GRACE_OPTION_BY_LOAN.equals(prProductTable.getGraceOption())
                //前一期逾期   宽限期置0
                //fix 宽限期内部分还款，原判断不对
                && amLoanAccountInfo.getContinueOverDueTenor() > 1) {
            graceDays = 0;
        }

        //罚息复利改造 起息日期需要计算
        //计息开始日期
        Date accrualFromDate = null;
        //计提开始日期 交易起息日
        Date accrualStartDate = null;
        int accrualTotalAccruDays = 0;
        Date lastGraceDate = DateUtils.addDay(amRepaymentPlanInfo.getPaymentDueDate(), graceDays);
        //1:还款日起息
        if (null == intrBeginDate || intrBeginDate.compareTo(lastGraceDate) <= 0) {
            if (TransBizConstant.PENALTY_VALUE_DATE_PAYMENT_DAY.equals(valueDate)) {
                accrualFromDate = DateUtils.addDay(businessDate, -1);
                accrualTotalAccruDays = Integer.max(DateUtils.getDiffDays(amRepaymentPlanInfo.getPaymentDueDate(), accrualFromDate) + 1, 0);
            } else if (TransBizConstant.PENALTY_VALUE_DATE_GRACE_DAY.equals(valueDate)) {//0:宽限日起息
                accrualFromDate = DateUtils.addDay(lastGraceDate, -1);
            }
            accrualStartDate = lastGraceDate;
        } else if (intrBeginDate.compareTo(lastGraceDate) > 0) {
            accrualFromDate = DateUtils.addDay(intrBeginDate, -1);
            accrualStartDate = intrBeginDate;
        }

        //罚息日利率
        //权益改造 将贷款信息表(AM_Loan_Main_Info)的原始利率orig_daily_rate写入累计账户信息(AM_Interest_Accrual_Info)上的日利率accrual_daily_rate
        BigDecimal dailyRate = penaltyRateTableService.getPenaltyDailyRate(amLoanMainInfo.getOrigDailyRate(), penaltyRateTable);

        if (accrualBaseAmount.compareTo(BigDecimal.ZERO) == 0) {
            return null;
        }
        AmInterestAccrualInfo amInterestAccrualInfo = new AmInterestAccrualInfo();
        BeanMapping.copy(amLoanMainInfo, amInterestAccrualInfo);
        try {
            amInterestAccrualInfo.setId(segmentService.getId(TransBizConstant.AM_INTEREST_ACCRUAL_INFO_ID));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }
        amInterestAccrualInfo.setAccrualDailyRate(dailyRate);
        amInterestAccrualInfo.setBillingTenor(amRepaymentPlanInfo.getBillingTenor());
        amInterestAccrualInfo.setAccountId(getAccountId(accountType, amLoanMainInfo.getTenantId(), amLoanMainInfo.getCustomerId()));//账户ID
        amInterestAccrualInfo.setAccountStatus(TransBizConstant.INTEREST_ACCRUAL_STATUS_1);//状态
        amInterestAccrualInfo.setAccountType(accountType);//类型 罚息累计账户
        amInterestAccrualInfo.setAccrualBaseAmount(accrualBaseAmount);//计息金额
        amInterestAccrualInfo.setAccrualStartDate(accrualStartDate);//交易起息日期  还款日加宽限期
        amInterestAccrualInfo.setAccrualTotalAccruInterest(BigDecimal.ZERO);//已累计总利息
        amInterestAccrualInfo.setAccrualTotalAccruDays(accrualTotalAccruDays);//已累计总天数
        amInterestAccrualInfo.setAccrualNewFromDate(accrualFromDate);//累计利息开始日期
        amInterestAccrualInfo.setStopAccrualFlag(TransBizConstant.STOP_ACCRU_FLAG_0);//停止累计息标志	0 = 正常计息  1 = 停止计息
        amInterestAccrualInfo.setMaxInterest(BigDecimal.ZERO);//最大利息金额
        amInterestAccrualInfo.setProfitShared(TransBizConstant.NO_FLAG);//是否已经分润	0 = 未分润 1 = 已分润  默认为0，未分润	初始固定值：0
        amInterestAccrualInfo.setBalTransferFlag(TransBizConstant.NO_FLAG);//债权转移标识
        amInterestAccrualInfo.setCompensatoryFlag(TransBizConstant.NO_FLAG);//代偿标识
        amInterestAccrualInfo.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);//	记录版本号	初始固定值：1
        amInterestAccrualInfo.setUpdateBy(TransBizConstant.SYS_OPRATE);
        amInterestAccrualInfo.setAccrualDailyAdjustment(BigDecimal.ZERO);
        amInterestAccrualInfo.setTaxAmt(BigDecimal.ZERO);
        amInterestAccrualInfo.setLiabilityFlag(amRepaymentPlanInfo.getLiabilityFlag());
        amInterestAccrualInfo.setProvisionalAccrualInterest(BigDecimal.ZERO);
        amInterestAccrualInfo.setProvisionalTaxAmt(BigDecimal.ZERO);

        //还款日计算
        Date patmentDueDate = DateUtils.addMonth(amRepaymentPlanInfo.getPaymentDueDate(), 1);
        if (TransBizConstant.YES_FLAG.equals(penaltyRateTable.getCastPenaltyPerMonth())) {
            patmentDueDate = DateUtils.calculationPayDate(amLoanMainInfo.getFirstPaymentDate(), businessDate);
        }

        amInterestAccrualInfo.setPaymentDueDate(patmentDueDate);
        amInterestAccrualInfo.setCreateTime(null);
        amInterestAccrualInfo.setUpdateTime(null);
        //会计状态
        amInterestAccrualInfo.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_1);
        //应计/非应计
        this.transNonAccrualsFlag(delqParamBean, amInterestAccrualInfo, amLoanAccountInfo);
        //五级分类
        amInterestAccrualInfo.setLoanClassify(amLoanAccountInfo.getLoanClassify());


        if (TransBizConstant.INTEREST_ACCRUAL_TYPE_10.equals(amInterestAccrualInfo.getAccountType())) {//罚息计提
            if (TransBizConstant.NON_ACCRUALS_FLA_0.equals(amInterestAccrualInfo.getNonAccrualsFlag())) {
                amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_PEN_INTR_ACCU);
            } else {
                amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_PEN_INTR_NONACCRUAL_ACCU);
            }
        } else if (TransBizConstant.INTEREST_ACCRUAL_TYPE_20.equals(amInterestAccrualInfo.getAccountType())) {//罚息计提
            if (TransBizConstant.NON_ACCRUALS_FLA_0.equals(amInterestAccrualInfo.getNonAccrualsFlag())) {
                amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_COM_INTR_ACCU);
            } else {
                amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_COM_INTR_NONACCRUAL_ACCU);
            }
        }

        return amInterestAccrualInfo;
    }

    /**
     * 抛账  抛分期费用账户
     *
     * @param amLoanMainInfo      订单
     * @param amRepaymentPlanInfo 当期还款计划
     * @param businessDate        业务日期
     * @return
     */
    @Override
    public CastAccountTransactionBean castInstallmentFeeAccount(AmLoanMainInfo amLoanMainInfo, AmLoanAccountInfo amLoanAccountInfo,
                                                                AmRepaymentPlanInfo amRepaymentPlanInfo, Date businessDate) throws TxnException {
        if (amRepaymentPlanInfo.getFeeAmount() == null || amRepaymentPlanInfo.getFeeAmount().compareTo(BigDecimal.ZERO) == 0) {
            return null;
        }
        AmAccountMainInfo feeAccount = new AmAccountMainInfo();
        BeanMapping.copy(amLoanMainInfo, feeAccount);
        try {
            feeAccount.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_ID));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }
        feeAccount.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_03, amLoanMainInfo.getTenantId(),
                amLoanMainInfo.getCustomerId()));//账户ID
        feeAccount.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        feeAccount.setAccountType(TransBizConstant.ACCOUNT_TYPE_03);//账户类型
        feeAccount.setTxnCode(TransBizConstant.TXN_CODE_INST_FEE);//交易码
        feeAccount.setPostingAmount(amRepaymentPlanInfo.getFeeAmount());//入账金额
        feeAccount.setPostingDate(businessDate);//入账时间
        feeAccount.setRepayAmount(BigDecimal.ZERO);//已还金额
        feeAccount.setBillingTenor(amRepaymentPlanInfo.getBillingTenor());//期次
        feeAccount.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        feeAccount.setCurrBalance(amRepaymentPlanInfo.getFeeAmount());//余额
        feeAccount.setInterestStartDate(businessDate);//交易起息日
        feeAccount.setPaymentDueDate(amRepaymentPlanInfo.getPaymentDueDate());//到期还款日
        feeAccount.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        feeAccount.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        feeAccount.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_1);
        feeAccount.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_1);
        feeAccount.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_0);
        feeAccount.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        feeAccount.setLiabilityFlag(amRepaymentPlanInfo.getLiabilityFlag());
        feeAccount.setTaxAmt(BigDecimal.ZERO);
        feeAccount.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        feeAccount.setCreateTime(null);
        feeAccount.setUpdateTime(null);
        feeAccount.setUpdateBy(TransBizConstant.SYS_OPRATE);

        //会计状态
        feeAccount.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);
        //应计/非应计
        feeAccount.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
        //五级分类
        feeAccount.setLoanClassify(amLoanAccountInfo.getLoanClassify());

        //更新订单上的余额  上层需更新订单 将更新字段入库
        amLoanAccountInfo.setCurrBalance(amLoanAccountInfo.getCurrBalance().add(feeAccount.getPostingAmount()));
        amLoanAccountInfo.setFeeBalance(amLoanAccountInfo.getFeeBalance().add(feeAccount.getPostingAmount()));
        //生成交易信息
        TlTransactionInfo tlTransactionInfo = tlTransactionInfoService.buildTlTransactionInfo(feeAccount,
                TransBizConstant.TRANSCATION_REVERSAL_FLAG_0);
        //生成GL流水
        TlGlInterfaceInfo tlGlInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(feeAccount, feeAccount.getPostingAmount(),
                feeAccount.getTxnCode(), feeAccount.getAccountingPhase(), businessDate);
        CastAccountTransactionBean castAccountTransactionBean = new CastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(feeAccount);
        castAccountTransactionBean.setTlTransactionInfo(tlTransactionInfo);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);
        return castAccountTransactionBean;
    }


    /**
     * 抛账   抛当期本金、费用、利息累计
     *
     * @param amLoanMainInfo          贷款订单
     * @param amRepaymentPlanInfoList 还款计划列表
     * @param businessDate            业务日期
     * @param isValid                 是否需要验证今天是否是抛账日
     * @return
     */
    @Override
    public CastAccountBean castTxnAccount(AmLoanMainInfo amLoanMainInfo, AmLoanAccountInfo amLoanAccountInfo,
                                          List<AmRepaymentPlanInfo> amRepaymentPlanInfoList, Date businessDate,
                                          Boolean isValid) throws TxnException {
        if (amLoanMainInfo == null) {
            return null;
        }
        logger.debug("开始抛帐loanId:{}", amLoanMainInfo.getLoanId());
        if (amLoanAccountInfo.getCastTenor() >= amLoanMainInfo.getTotalTenor()) {//如果订单已抛期数等于订单总期数，返回
            return null;
        }

        //获取订单属性值
        Integer billingTenor = amLoanAccountInfo.getCastTenor() + 1;
        if (billingTenor > amLoanMainInfo.getTotalTenor()) {
            //尾期已抛帐
            return null;
        }

        AmRepaymentPlanInfo prePlan = this.getRepaymentPlanInfo(amLoanAccountInfo.getCastTenor(), amRepaymentPlanInfoList);

        if (isValid) {
            //是否验证今天是抛账日
            if (prePlan != null && prePlan.getPaymentDueDate().compareTo(businessDate) != 0) {
                return null;
            }
        }

        AmRepaymentPlanInfo currPlan = this.getRepaymentPlanInfo(billingTenor, amRepaymentPlanInfoList);
        if (currPlan == null) {
            logger.error("订单号：{} 当前期[{}]计划为空", amLoanMainInfo.getLoanId(), billingTenor);
            throw new TxnRuntimeException("获取当期还款计划失败");
        }

        CastAccountBean castAccountBean = new CastAccountBean();

        logger.debug("是抛帐日，开始生成本利费交易账户 loanId:{}", amLoanMainInfo.getLoanId());

        DelqParamBean delqParamBean = delqService.buildDqlqAccountBean(amLoanMainInfo.getTenantId(), amLoanMainInfo.getDelqTableId());

        //抛账  本金账户
        CastAccountTransactionBean castPrincipalAccount = castPrincipalAccount(amLoanMainInfo, amLoanAccountInfo, currPlan, delqParamBean, businessDate);
        castAccountBean.addAccountMainInfo(castPrincipalAccount.getAmAccountMainInfo());
        castAccountBean.addTransactionInfoList(castPrincipalAccount.getTlTransactionInfo());
        castAccountBean.addAllTlGlInterfaceInfo(castPrincipalAccount.getTlGlInterfaceInfoList());

        //查询利率参数
        PrInterestTable interestTable = interestTableService.findInterestByInterestId(amLoanMainInfo.getInterestTableId(), amLoanMainInfo.getTenantId());
        if (interestTable == null) {
            logger.error("获取利率参数{}失败", amLoanMainInfo.getInterestTableId());
            throw new TxnRuntimeException("获取利率参数" + amLoanMainInfo.getInterestTableId() + "失败");
        }

        String accrualBasic = interestTable.getAccrualBasic();//计息基础  0 = 剩余本金   1 = 贷款本金
        BigDecimal accrualBaseAmount = null;
        if (TransBizConstant.ACCRUAL_BASIC_0.equals(accrualBasic)) {
            accrualBaseAmount = getPlanPrinBalance(amRepaymentPlanInfoList, billingTenor);
        } else if (TransBizConstant.ACCRUAL_BASIC_1.equals(accrualBasic)) {
            accrualBaseAmount = amLoanMainInfo.getLoanAmount();
        }

        //生成利息累计
        if (!TransBizConstant.START_DATE_FLAG_2.equals(interestTable.getStartDateFlag())) {
            AmInterestAccrualInfo amInterestAccrualInfo = castInterestAccrualAccount(currPlan,
                    castPrincipalAccount.getAmAccountMainInfo(), amLoanAccountInfo, amLoanMainInfo, accrualBaseAmount, delqParamBean);
            castAccountBean.addInterestAccrualInfo(amInterestAccrualInfo);
        }


        //生成分期费用账户
        CastAccountTransactionBean castInstallmentFeeAccount = null;
        if (StringUtils.isNotBlank(amLoanMainInfo.getFeeTableId())) {
            castInstallmentFeeAccount = castInstallmentFeeAccount(amLoanMainInfo,
                    amLoanAccountInfo, currPlan, businessDate);
        }
        if (castInstallmentFeeAccount != null) {
            castAccountBean.addAccountMainInfo(castInstallmentFeeAccount.getAmAccountMainInfo());
            castAccountBean.addTransactionInfoList(castInstallmentFeeAccount.getTlTransactionInfo());
            castAccountBean.addAllTlGlInterfaceInfo(castInstallmentFeeAccount.getTlGlInterfaceInfoList());
        }

        //更新订单信息
        AmLoanAccountInfo updateLoanAccount = new AmLoanAccountInfo();
        updateLoanAccount.setId(amLoanAccountInfo.getId());
        updateLoanAccount.setCustomerId(amLoanAccountInfo.getCustomerId());
        updateLoanAccount.setTenantId(amLoanAccountInfo.getTenantId());
        updateLoanAccount.setOrganizationId(amLoanAccountInfo.getOrganizationId());
        if (amLoanAccountInfo.getCastTenor() == 0 && TransBizConstant.LOAN_STATUS_0.equals(amLoanAccountInfo.getAccountStatus())) {
            updateLoanAccount.setAccountStatus(TransBizConstant.LOAN_STATUS_1);
            amLoanAccountInfo.setAccountStatus(TransBizConstant.LOAN_STATUS_1);
        }
        updateLoanAccount.setCastTenor(billingTenor);
        amLoanAccountInfo.setCastTenor(billingTenor);
        updateLoanAccount.setCurrBalance(amLoanAccountInfo.getCurrBalance());
        updateLoanAccount.setPrincipalBalance(amLoanAccountInfo.getPrincipalBalance());
        updateLoanAccount.setFeeBalance(amLoanAccountInfo.getFeeBalance());
        updateLoanAccount.setNextPaymentDate(currPlan.getPaymentDueDate());
        amLoanAccountInfo.setNextPaymentDate(currPlan.getPaymentDueDate());
        castAccountBean.addUpdateLoanAccount(updateLoanAccount);

        //更新还款计划
        AmRepaymentPlanInfo updateCurrPlan = new AmRepaymentPlanInfo();
        updateCurrPlan.setId(currPlan.getId());
        updateCurrPlan.setCustomerId(currPlan.getCustomerId());
        updateCurrPlan.setTenantId(currPlan.getTenantId());
        updateCurrPlan.setOrganizationId(currPlan.getOrganizationId());

        updateCurrPlan.setPlanStatus(TransBizConstant.LOAN_PLAN_STATUS_1);
        currPlan.setPlanStatus(TransBizConstant.LOAN_PLAN_STATUS_1);
        castAccountBean.addUpdateRepaymentPlan(updateCurrPlan);

        logger.debug("抛帐结束loanId:{}", amLoanMainInfo.getLoanId());
        return castAccountBean;
    }

    /**
     * 得到当期还款计划明细
     *
     * @param tenor
     * @param amRepaymentPlanInfoList
     * @return
     */
    @Override
    public AmRepaymentPlanInfo getRepaymentPlanInfo(Integer tenor, List<AmRepaymentPlanInfo> amRepaymentPlanInfoList) {
        AmRepaymentPlanInfo curr = null;
        if (tenor == null) {
            return null;
        }
        for (AmRepaymentPlanInfo tmp : amRepaymentPlanInfoList) {
            if (Objects.equals(tenor, tmp.getBillingTenor())) {
                curr = tmp;
                break;
            }
        }
        return curr;
    }

    /**
     * 得到当期还款计划明细
     *
     * @param tenor
     * @param amWaiveRepaymentPlanInfoList
     * @return
     */
    public AmWaiveRepaymentPlanInfo getWaiveRepaymentPlanInfo(Integer tenor, List<AmWaiveRepaymentPlanInfo> amWaiveRepaymentPlanInfoList) {
        AmWaiveRepaymentPlanInfo curr = null;
        if (tenor == null) {
            return null;
        }
        for (AmWaiveRepaymentPlanInfo tmp : amWaiveRepaymentPlanInfoList) {
            if (Objects.equals(tenor, tmp.getBillingTenor())) {
                curr = tmp;
                break;
            }
        }
        return curr;
    }

    /**
     * 获取订单计划剩余本金金额
     *
     * @param repaymentPlanInfoList
     * @param billingTenor
     * @return
     */
    @Override
    public BigDecimal getPlanPrinBalance(List<AmRepaymentPlanInfo> repaymentPlanInfoList, Integer billingTenor) {
        BigDecimal prinBalance = BigDecimal.ZERO;
        for (AmRepaymentPlanInfo repaymentPlanInfo : repaymentPlanInfoList) {
            if (repaymentPlanInfo.getBillingTenor() >= billingTenor) {
                prinBalance = prinBalance.add(repaymentPlanInfo.getPrincipalAmount()).subtract(repaymentPlanInfo.getRepayPrincipal());
            }
        }
        return prinBalance;
    }

    /**
     * 抛出提前还款／提前结清费用账户
     *
     * @param amLoanMainInfo
     * @param feeTxnCode
     * @param fee
     * @param businessDate
     * @return
     * @throws TxnBizException
     */
    @Override
    public CastAccountTransactionBean castPaymentFeeAccount(AmLoanMainInfo amLoanMainInfo, AmLoanAccountInfo amLoanAccountInfo, String feeTxnCode, BigDecimal fee, Date businessDate, String liabilityFlag) throws TxnException {
        AmAccountMainInfo feeAccount = new AmAccountMainInfo();
        BeanMapping.copy(amLoanMainInfo, feeAccount);
        try {
            feeAccount.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }
        feeAccount.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_03, amLoanMainInfo.getTenantId(), amLoanMainInfo.getCustomerId()));//账户ID
        feeAccount.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        feeAccount.setAccountType(TransBizConstant.ACCOUNT_TYPE_03);//账户类型
        feeAccount.setBillingTenor(amLoanAccountInfo.getCastTenor());
        feeAccount.setTxnCode(feeTxnCode);//交易码
        feeAccount.setPostingAmount(fee);//入账金额
        feeAccount.setPostingDate(businessDate);//入账时间
        feeAccount.setRepayAmount(BigDecimal.ZERO);//已还金额
        feeAccount.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        feeAccount.setCurrBalance(fee);//余额
        feeAccount.setInterestStartDate(businessDate);//交易起息日
        feeAccount.setPaymentDueDate(businessDate);//到期还款日
        feeAccount.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        feeAccount.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        feeAccount.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_1);
        feeAccount.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_1);
        feeAccount.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_0);
        feeAccount.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        feeAccount.setLiabilityFlag(liabilityFlag);
        feeAccount.setTaxAmt(BigDecimal.ZERO);
        feeAccount.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        feeAccount.setCreateTime(null);
        feeAccount.setUpdateTime(null);
        feeAccount.setUpdateBy(TransBizConstant.SYS_OPRATE);

        //会计状态
        feeAccount.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);
        //应计/非应计
        feeAccount.setNonAccrualsFlag(TransBizConstant.NON_ACCRUALS_FLA_0);
        //五级分类
        feeAccount.setLoanClassify(amLoanAccountInfo.getLoanClassify());
        //生成交易信息
        TlTransactionInfo tlTransactionInfo = tlTransactionInfoService.buildTlTransactionInfo(feeAccount,
                TransBizConstant.TRANSCATION_REVERSAL_FLAG_0);
        //生成GL流水
        TlGlInterfaceInfo tlGlInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(feeAccount, feeAccount.getPostingAmount(),
                feeAccount.getTxnCode(), feeAccount.getAccountingPhase(), businessDate);
        CastAccountTransactionBean castAccountTransactionBean = new CastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(feeAccount);
        castAccountTransactionBean.setTlTransactionInfo(tlTransactionInfo);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);
        return castAccountTransactionBean;
    }

    /**
     * 根据还款计划抛出利息交易账户
     *
     * @param amLoanMainInfo      订单
     * @param amRepaymentPlanInfo 当期还款计划
     * @param businessDate        业务日期
     * @return
     * @throws TxnBizException
     */
    @Override
    public CastAccountTransactionBean castIntrAccount(AmLoanMainInfo amLoanMainInfo, AmLoanAccountInfo amLoanAccountInfo,
                                                      AmRepaymentPlanInfo amRepaymentPlanInfo, DelqParamBean delqParamBean, Date businessDate) throws TxnException {
        AmAccountMainInfo intrAcct = new AmAccountMainInfo();
        BeanMapping.copy(amLoanMainInfo, intrAcct);
        try {
            intrAcct.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_ID));//
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }
        intrAcct.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_04, amLoanMainInfo.getTenantId(),
                amLoanMainInfo.getCustomerId()));
        //账户ID 生成规则
        intrAcct.setAccountType(TransBizConstant.ACCOUNT_TYPE_04);//账户类型
        intrAcct.setTxnCode(TransBizConstant.TXN_CODE_INST_INTR);
        intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        intrAcct.setBillingTenor(amRepaymentPlanInfo.getBillingTenor());//期次
        intrAcct.setPostingAmount(amRepaymentPlanInfo.getInterestAmount());//入账金额
        intrAcct.setCurrBalance(amRepaymentPlanInfo.getInterestAmount());//余额
        intrAcct.setRepayAmount(BigDecimal.ZERO);//已还金额
        intrAcct.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        intrAcct.setPaymentDueDate(amRepaymentPlanInfo.getPaymentDueDate());//到期还款日
        intrAcct.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        intrAcct.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_1);
        intrAcct.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_1);
        intrAcct.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_0);
        intrAcct.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        intrAcct.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        intrAcct.setLiabilityFlag(amRepaymentPlanInfo.getLiabilityFlag());
        intrAcct.setCreateTime(null);
        intrAcct.setUpdateTime(null);
        intrAcct.setUpdateBy(TransBizConstant.SYS_OPRATE);
        //会计状态
        intrAcct.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);
        //应计/非应计
        this.transNonAccrualsFlag(delqParamBean, intrAcct, amLoanAccountInfo);
        //五级分类
        intrAcct.setLoanClassify(amLoanAccountInfo.getLoanClassify());

        //更新订单上的余额  上层需更新订单 将更新字段入库
        amLoanAccountInfo.setCurrBalance(amLoanAccountInfo.getCurrBalance().add(intrAcct.getPostingAmount()));
        amLoanAccountInfo.setInterestBalance(amLoanAccountInfo.getInterestBalance().add(intrAcct.getPostingAmount()));
        //生成交易信息
        TlTransactionInfo tlTransactionInfo = tlTransactionInfoService.buildTlTransactionInfo(intrAcct,
                TransBizConstant.TRANSCATION_REVERSAL_FLAG_0);

        //价税分离
        BigDecimal taxAmt = BigDecimal.ZERO;
        PrInterestTable prInterestTable = interestTableService.findInterestByInterestId(intrAcct.getInterestTableId(), intrAcct.getTenantId());
        if (TransBizConstant.TAX_FLAG_0.equals(prInterestTable.getTaxFlag())) {
            //税金=含税收入金额/（1+税率）*税率计算每日利息的税金
            taxAmt = intrAcct.getPostingAmount().multiply(prInterestTable.getTaxRate()).divide(BigDecimal.ONE.add(prInterestTable.getTaxRate()), TransBizConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
            intrAcct.setTaxAmt(taxAmt);
        }

        //生成GL流水
        TlGlInterfaceInfo tlGlInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(intrAcct, intrAcct.getPostingAmount().subtract(taxAmt),
                intrAcct.getTxnCode(), intrAcct.getAccountingPhase(), businessDate);
        CastAccountTransactionBean castAccountTransactionBean = new CastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(intrAcct);
        castAccountTransactionBean.setTlTransactionInfo(tlTransactionInfo);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);

        TlGlInterfaceInfo taxTlGlInterfaceInfo = glInterfaceService.buildTaxTlGlInterfaceInfo(intrAcct, intrAcct.getPostingAmount(), taxAmt, TransBizConstant.TXN_CODE_INST_INTR_TAX
                , intrAcct.getAccountingPhase(), businessDate);
        castAccountTransactionBean.addTlGlInterfaceInfo(taxTlGlInterfaceInfo);
        return castAccountTransactionBean;
    }

    @Override
    public String getAccountId(String accountType, String tenantId, String customerId) {
        StringBuilder stringBuilder = new StringBuilder();
        //取客户后2位
        String customerSuffix = StringUtils.right(customerId, TransBizConstant.ACCOUNT_ID_CUSTOMER_PLACE);
        //accountType(2位)+tenant_id(4位)+customer_id后2位+yyyyMMddHHmmssSSS(17位)+7位随机
        stringBuilder.append(accountType).append(tenantId).append(customerSuffix).append(SeqUtils.getSNByLength(TransBizConstant.ACCOUNT_ID_RANDOM_PLACE));
        return stringBuilder.toString();
    }

    @Override
    public AmDelinquencyInfo generateDelinquencyInfo(AmLoanMainInfo amLoanMainInfo, AmRepaymentPlanInfo amRepaymentPlanInfo, Date businessdate, Integer delqDays) throws TxnBizException {
        AmDelinquencyInfo amDelinquencyInfo = new AmDelinquencyInfo();
        BeanMapping.copy(amRepaymentPlanInfo, amDelinquencyInfo);
        try {
            amDelinquencyInfo.setId(segmentService.getId(TransBizConstant.AM_DELINQUENCY_INFO_ID));//
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }
        amDelinquencyInfo.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_50, amLoanMainInfo.getTenantId(),
                amLoanMainInfo.getCustomerId()));
        amDelinquencyInfo.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        amDelinquencyInfo.setAccountType(TransBizConstant.ACCOUNT_TYPE_50);
        amDelinquencyInfo.setDelqDate(businessdate);
        amDelinquencyInfo.setDelqDays(delqDays);
        amDelinquencyInfo.setLastDelqDays(0);
        //当期本金(principal_amount)-当前已还本金(repay_principal)+当期利息(interest_amount)-当期已还利息(repay_interest)+当期费用(fee_amount)-当期已还费用(repay_fee)
        BigDecimal totalAmountDue = amRepaymentPlanInfo.getPrincipalAmount().subtract(amRepaymentPlanInfo.getRepayPrincipal())
                .add(amRepaymentPlanInfo.getInterestAmount()).subtract(amRepaymentPlanInfo.getRepayInterest())
                .add(amRepaymentPlanInfo.getFeeAmount()).subtract(amRepaymentPlanInfo.getRepayFee());
        amDelinquencyInfo.setTotalAmountDue(totalAmountDue);
        amDelinquencyInfo.setDelqProcessTableId(amLoanMainInfo.getDelqTableId());
        amDelinquencyInfo.setPenaltyTableId(amLoanMainInfo.getPenaltyTableId());
        amDelinquencyInfo.setJointLoanFlag(amLoanMainInfo.getJointLoanFlag());
        amDelinquencyInfo.setFundId(amLoanMainInfo.getFundId());
        amDelinquencyInfo.setCreateTime(null);
        amDelinquencyInfo.setUpdateTime(null);
        amDelinquencyInfo.setUpdateBy(TransBizConstant.SYS_OPRATE);
        return amDelinquencyInfo;
    }

    /**
     * 核销 本金账户抛账
     *
     * @param amLoanMainInfo
     * @param amLoanAccountInfo
     * @param amRepaymentPlanInfo
     * @param delqParamBean
     * @param businessDate
     * @return
     * @throws TxnException
     */
    @Override
    public CastAccountTransactionBean castPrincipalAccountByChargeoff(AmLoanMainInfo amLoanMainInfo, AmLoanAccountInfo amLoanAccountInfo, AmRepaymentPlanInfo amRepaymentPlanInfo, DelqParamBean delqParamBean, Date businessDate) throws TxnException {
        AmAccountMainInfo amAccountMainInfo = new AmAccountMainInfo();
        BeanMapping.copy(amLoanMainInfo, amAccountMainInfo);
        try {
            amAccountMainInfo.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_ID));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }
        amAccountMainInfo.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_06, amAccountMainInfo.getTenantId()
                , amLoanMainInfo.getCustomerId()));//账户ID
        amAccountMainInfo.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        amAccountMainInfo.setAccountType(TransBizConstant.ACCOUNT_TYPE_06);//账户类型
        amAccountMainInfo.setTxnCode(TransBizConstant.TXN_CODE_INST);//本金交易账户
        amAccountMainInfo.setBillingTenor(amRepaymentPlanInfo.getBillingTenor());//第几期	　
        amAccountMainInfo.setPostingAmount(amRepaymentPlanInfo.getPrincipalAmount());//入账金额
        amAccountMainInfo.setPostingDate(businessDate);//入账时间
        amAccountMainInfo.setRepayAmount(BigDecimal.ZERO);//已还金额
        amAccountMainInfo.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        amAccountMainInfo.setCurrBalance(amRepaymentPlanInfo.getPrincipalAmount());//余额
        amAccountMainInfo.setInterestStartDate(businessDate);//交易起息日
        amAccountMainInfo.setPaymentDueDate(amRepaymentPlanInfo.getPaymentDueDate());//到期还款日
        amAccountMainInfo.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        amAccountMainInfo.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        amAccountMainInfo.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_0);//停费
        amAccountMainInfo.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_0);//停止计息
        amAccountMainInfo.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_1);//核销标识
        amAccountMainInfo.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        amAccountMainInfo.setChargeoffAmount(amRepaymentPlanInfo.getPrincipalAmount());
        amAccountMainInfo.setChargeoffDate(businessDate);
        amAccountMainInfo.setLiabilityFlag(amRepaymentPlanInfo.getLiabilityFlag());
        amAccountMainInfo.setTaxAmt(BigDecimal.ZERO);
        amAccountMainInfo.setCreateTime(null);
        amAccountMainInfo.setUpdateTime(null);
        amAccountMainInfo.setUpdateBy(TransBizConstant.SYS_OPRATE);

        //会计标志
        amAccountMainInfo.setAccountingPhase(amLoanAccountInfo.getAccountingPhase());
        //应计/非应计
        this.transNonAccrualsFlag(delqParamBean, amAccountMainInfo, amLoanAccountInfo);
        //五级分类
        amAccountMainInfo.setLoanClassify(amLoanAccountInfo.getLoanClassify());

        //更新订单上的余额  上层需更新订单 将更新字段入库
        amLoanAccountInfo.setCurrBalance(amLoanAccountInfo.getCurrBalance().add(amAccountMainInfo.getPostingAmount()));
        amLoanAccountInfo.setPrincipalBalance(amLoanAccountInfo.getPrincipalBalance().add(amAccountMainInfo.getPostingAmount()));

        //生成交易信息
        TlTransactionInfo tlTransactionInfo = tlTransactionInfoService.buildTlTransactionInfo(amAccountMainInfo,
                TransBizConstant.TRANSCATION_REVERSAL_FLAG_0);
        //生成一条核销本金Gl流水
        TlGlInterfaceInfo tlGlInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(amAccountMainInfo, amAccountMainInfo.getPostingAmount(),
                TransBizConstant.TXN_CHARGEOFF_CODE_PRINCIPAL, amAccountMainInfo.getAccountingPhase(), businessDate);
        CastAccountTransactionBean castAccountTransactionBean = new CastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(amAccountMainInfo);
        castAccountTransactionBean.setTlTransactionInfo(tlTransactionInfo);
        castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);
        return castAccountTransactionBean;
    }

    /**
     * 核销累计账户抛账  抛出交易账户
     *
     * @param amLoanMainInfo
     * @param amInterestAccrualInfo
     * @return
     */
    @Override
    public CastAccountTransactionBean castInterestAccountByChargeoff(AmLoanMainInfo amLoanMainInfo, AmLoanAccountInfo amLoanAccountInfo,
                                                                     AmInterestAccrualInfo amInterestAccrualInfo, Date businessDate, String reasonCode) throws TxnException {

        AmAccountMainInfo intrAcct = new AmAccountMainInfo();
        BeanMapping.copy(amLoanMainInfo, intrAcct);
        try {
            intrAcct.setId(segmentService.getId(TransBizConstant.AM_ACCOUNT_ID));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(ErrorMsgConstant.ERROR_ID);
        }

        intrAcct.setPostingAmount(amInterestAccrualInfo.getAccrualTotalAccruInterest());//入账金额
        intrAcct.setCurrBalance(amInterestAccrualInfo.getAccrualTotalAccruInterest());//余额
        intrAcct.setRepayAmount(BigDecimal.ZERO);//已还金额
        intrAcct.setCreditAdjustAmount(BigDecimal.ZERO);//贷调金额	调整金额(免除金额)
        intrAcct.setPaymentDueDate(amInterestAccrualInfo.getPaymentDueDate());//到期还款日
        intrAcct.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        intrAcct.setOriginalAccountId(amInterestAccrualInfo.getAccountId());
        intrAcct.setBillingTenor(amInterestAccrualInfo.getBillingTenor());
        intrAcct.setPostingDate(businessDate);
        intrAcct.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        intrAcct.setInterestStartDate(amInterestAccrualInfo.getAccrualStartDate());
        intrAcct.setAccountingPhase(amInterestAccrualInfo.getAccountingPhase());
        intrAcct.setNonAccrualsFlag(amInterestAccrualInfo.getNonAccrualsFlag());
        intrAcct.setLoanClassify(amLoanAccountInfo.getLoanClassify());
        intrAcct.setCompensatoryDays(TransBizConstant.ZERO);//	代偿天数初始0
        intrAcct.setWaiveFeeFlag(TransBizConstant.WAIVE_FEE_FLAG_0);
        intrAcct.setWaiveInterestFlag(TransBizConstant.WAIVE_INTEREST_FLAG_0);
        intrAcct.setChargeoffFlag(TransBizConstant.CHARGOFF_FLAG_1);
        intrAcct.setCompensatoryFlag(TransBizConstant.COMPENSATORY_FLAG_0);
        intrAcct.setChargeoffAmount(amInterestAccrualInfo.getAccrualTotalAccruInterest());
        intrAcct.setChargeoffDate(businessDate);
        intrAcct.setChargeoffReasonCode(reasonCode);
        intrAcct.setTaxAmt(amInterestAccrualInfo.getTaxAmt());
        intrAcct.setLiabilityFlag(amInterestAccrualInfo.getLiabilityFlag());

        String chargeoTxnCode = "";
        String accuTxnCode = amInterestAccrualInfo.getTxnCode();
        String txnCode = accuTxnCode.substring(0, 1) + (Integer.parseInt(accuTxnCode.substring(1)) - 10);
        intrAcct.setTxnCode(txnCode);

        //利息
        if (TransBizConstant.INTEREST_ACCRUAL_TYPE_66.equals(amInterestAccrualInfo.getAccountType())) {
            chargeoTxnCode = TransBizConstant.TXN_CHARGEOFF_CODE_INTR;
            intrAcct.setAccountType(TransBizConstant.ACCOUNT_TYPE_04);//账户类型
            intrAcct.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_04, amLoanMainInfo.getTenantId(),
                    amLoanMainInfo.getCustomerId()));
            //更新订单上的余额  上层需更新订单 将更新字段入库
            amLoanAccountInfo.setCurrBalance(amLoanAccountInfo.getCurrBalance().add(intrAcct.getPostingAmount()));
            amLoanAccountInfo.setInterestBalance(amLoanAccountInfo.getInterestBalance().add(intrAcct.getPostingAmount()));
            amLoanAccountInfo.setAccruedInterest(amLoanAccountInfo.getAccruedInterest().subtract(intrAcct.getPostingAmount()));
            intrAcct.setPaymentDueDate(amInterestAccrualInfo.getPaymentDueDate());//到期还款日
            intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        } else if (TransBizConstant.INTEREST_ACCRUAL_TYPE_10.equals(amInterestAccrualInfo.getAccountType())) {//罚息
            chargeoTxnCode = TransBizConstant.TXN_CHARGEOFF_CODE_PEN_INTR;
            intrAcct.setAccountType(TransBizConstant.ACCOUNT_TYPE_11);//账户类型
            intrAcct.setTxnCode(txnCode);
            intrAcct.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_11, amLoanMainInfo.getTenantId(),
                    amLoanMainInfo.getCustomerId()));
            //更新订单上的罚息余额
            amLoanAccountInfo.setPenaltyBalance(amLoanAccountInfo.getPenaltyBalance().add(intrAcct.getPostingAmount()));
            amLoanAccountInfo.setAccruedPenalty(amLoanAccountInfo.getAccruedPenalty().subtract(intrAcct.getPostingAmount()));
            intrAcct.setPaymentDueDate(businessDate);//到期还款日
            intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        } else if (TransBizConstant.INTEREST_ACCRUAL_TYPE_20.equals(amInterestAccrualInfo.getAccountType())) {//复利
            chargeoTxnCode = TransBizConstant.TXN_CHARGEOFF_CODE_COMP_INTR;
            intrAcct.setAccountType(TransBizConstant.ACCOUNT_TYPE_12);//账户类型  复利
            intrAcct.setAccountId(getAccountId(TransBizConstant.ACCOUNT_TYPE_12, amLoanMainInfo.getTenantId(),
                    amLoanMainInfo.getCustomerId()));
            //更新订单上的复利余额
            amLoanAccountInfo.setCompoundBalance(amLoanAccountInfo.getCompoundBalance().add(intrAcct.getPostingAmount()));
            amLoanAccountInfo.setAccruedCompound(amLoanAccountInfo.getAccruedCompound().subtract(intrAcct.getPostingAmount()));
            intrAcct.setPaymentDueDate(businessDate);//到期还款日
            intrAcct.setAccountStatus(TransBizConstant.ACCOUNT_STATUS_1);
        }

        intrAcct.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        intrAcct.setCreateTime(null);
        intrAcct.setUpdateTime(null);
        intrAcct.setUpdateBy(TransBizConstant.SYS_OPRATE);
        //生成交易信息
        TlTransactionInfo tlTransactionInfo = tlTransactionInfoService.buildTlTransactionInfo(intrAcct,
                TransBizConstant.TRANSCATION_REVERSAL_FLAG_0);
        //生成核销Gl流水
        TlGlInterfaceInfo tlGlInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(intrAcct, intrAcct.getPostingAmount().subtract(intrAcct.getTaxAmt()),
                chargeoTxnCode, intrAcct.getAccountingPhase(), businessDate);


        //还需生成一条原GL流水
        TlGlInterfaceInfo oldTlGlInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(intrAcct, intrAcct.getPostingAmount().subtract(intrAcct.getTaxAmt()),
                txnCode, intrAcct.getAccountingPhase(), businessDate);


        CastAccountTransactionBean castAccountTransactionBean = new CastAccountTransactionBean();
        castAccountTransactionBean.setAmAccountMainInfo(intrAcct);
        castAccountTransactionBean.setTlTransactionInfo(tlTransactionInfo);
        if (null != tlGlInterfaceInfo) {
            castAccountTransactionBean.addTlGlInterfaceInfo(tlGlInterfaceInfo);
        }
        if (null != oldTlGlInterfaceInfo) {
            castAccountTransactionBean.addTlGlInterfaceInfo(oldTlGlInterfaceInfo);
        }

        //价税分离
        String tranCode = "";
        if (TransBizConstant.INTEREST_ACCRUAL_TYPE_66.equals(amInterestAccrualInfo.getAccountType())) {
            tranCode = TransBizConstant.TXN_CHARGEOFF_CODE_INTR_TAX;
        } else if (TransBizConstant.INTEREST_ACCRUAL_TYPE_10.equals(amInterestAccrualInfo.getAccountType())) {//罚息计提
            tranCode = TransBizConstant.TXN_CHARGEOFF_CODE_PEN_INTR_TAX;
        } else if (TransBizConstant.INTEREST_ACCRUAL_TYPE_20.equals(amInterestAccrualInfo.getAccountType())) {//罚息计提
            tranCode = TransBizConstant.TXN_CHARGEOFF_CODE_COMP_INTR_TAX;
        }
        TlGlInterfaceInfo taxTlGlInterfaceInfo = glInterfaceService.buildTlGlInterfaceInfo(intrAcct, intrAcct.getTaxAmt(), tranCode
                , intrAcct.getAccountingPhase(), businessDate);
        if (null != taxTlGlInterfaceInfo) {
            castAccountTransactionBean.addTlGlInterfaceInfo(taxTlGlInterfaceInfo);
        }
        return castAccountTransactionBean;
    }

    @Override
    public CastWaiveAccountBean castTxnWaiveAccount(AmLoanMainInfo amLoanMainInfo, AmLoanAccountInfo amLoanAccountInfo, List<AmWaiveRepaymentPlanInfo> waiveRepaymentPlanInfoList
            , List<AmRepaymentPlanInfo> amRepaymentPlanInfoList, Date businessDate, Boolean isValid) throws TxnException {
        if (amLoanMainInfo == null) {
            return null;
        }
        logger.debug("开始抛帐loanId:{}", amLoanMainInfo.getLoanId());
        if (amLoanAccountInfo.getCastTenor() >= amLoanMainInfo.getTotalTenor()) {//如果订单已抛期数等于订单总期数，返回
            return null;
        }

        if (TransBizConstant.WAIVE_TYPE_0.equals(amLoanMainInfo.getWaiveType())) {
            return null;
        }

        if (CollectionUtils.isEmpty(waiveRepaymentPlanInfoList)) {
            return null;
        }

        //获取订单属性值
        Integer billingTenor = amLoanAccountInfo.getCastTenor() + 1;
        if (billingTenor > amLoanMainInfo.getTotalTenor()) {
            //尾期已抛帐
            return null;
        }

        AmWaiveRepaymentPlanInfo prePlan = this.getWaiveRepaymentPlanInfo(amLoanAccountInfo.getCastTenor(), waiveRepaymentPlanInfoList);

        if (isValid) {
            //是否验证今天是抛账日
            if (prePlan != null && prePlan.getPaymentDueDate().compareTo(businessDate) != 0) {
                return null;
            }
        }

        AmWaiveRepaymentPlanInfo currWaivePlan = this.getWaiveRepaymentPlanInfo(billingTenor, waiveRepaymentPlanInfoList);

        if (currWaivePlan == null) {
            return null;
        }

        CastWaiveAccountBean castWaiveAccountBean = new CastWaiveAccountBean();

        logger.debug("是抛帐日，开始生成贴息累计账户 loanId:{}", amLoanMainInfo.getLoanId());

        DelqParamBean delqParamBean = delqService.buildDqlqAccountBean(amLoanMainInfo.getTenantId(), amLoanMainInfo.getDelqTableId());

        //查询利率参数
        String accrualBasic = "";
        if (TransBizConstant.WAIVE_TYPE_1.equals(amLoanMainInfo.getWaiveType())) {
            PrWaiveInterestTableRes prWaiveInterestTable = prWaiveInterestTableService.findByTenIdAndInterestId(amLoanMainInfo.getTenantId(), amLoanMainInfo.getWaiveInterestId());
            if (prWaiveInterestTable == null) {
                logger.error("获取贴息利率参数{}失败", amLoanMainInfo.getWaiveInterestId());
                throw new TxnRuntimeException("获取贴息利率参数" + amLoanMainInfo.getWaiveInterestId() + "失败");
            }
            accrualBasic = prWaiveInterestTable.getAccrualBasic();//计息基础  0 = 剩余本金   1 = 贷款本金
        }

        if (TransBizConstant.WAIVE_TYPE_2.equals(amLoanMainInfo.getWaiveType()) || TransBizConstant.WAIVE_TYPE_3.equals(amLoanMainInfo.getWaiveType())) {
            PrInterestTable prInterestTable = interestTableService.findInterestByInterestId(amLoanMainInfo.getInterestTableId(), amLoanMainInfo.getTenantId());
            if (prInterestTable == null) {
                logger.error("获取利率参数{}失败", amLoanMainInfo.getInterestTableId());
                throw new TxnRuntimeException("获取利率参数" + amLoanMainInfo.getInterestTableId() + "失败");
            }
            accrualBasic = prInterestTable.getAccrualBasic();//计息基础  0 = 剩余本金   1 = 贷款本金
        }

        BigDecimal accrualBaseAmount = null;
        if (TransBizConstant.ACCRUAL_BASIC_0.equals(accrualBasic)) {
            accrualBaseAmount = getPlanPrinBalance(amRepaymentPlanInfoList, billingTenor);
        } else if (TransBizConstant.ACCRUAL_BASIC_1.equals(accrualBasic)) {
            accrualBaseAmount = amLoanMainInfo.getLoanAmount();
        }

        //生成利息累计
        AmInterestAccrualInfo amInterestAccrualInfo = castWaiveInterestAccrualAccount(currWaivePlan, amLoanAccountInfo,
                amLoanMainInfo, accrualBaseAmount, delqParamBean);
        castWaiveAccountBean.addInterestAccrualInfo(amInterestAccrualInfo);


        //更新还款计划
        AmWaiveRepaymentPlanInfo updateWaiveCurrPlan = new AmWaiveRepaymentPlanInfo();
        updateWaiveCurrPlan.setId(currWaivePlan.getId());
        updateWaiveCurrPlan.setCustomerId(currWaivePlan.getCustomerId());
        updateWaiveCurrPlan.setTenantId(currWaivePlan.getTenantId());
        updateWaiveCurrPlan.setOrganizationId(currWaivePlan.getOrganizationId());

        updateWaiveCurrPlan.setPlanStatus(TransBizConstant.LOAN_PLAN_STATUS_1);
        currWaivePlan.setPlanStatus(TransBizConstant.LOAN_PLAN_STATUS_1);
        castWaiveAccountBean.addUpdateWaiveRepaymentPlan(updateWaiveCurrPlan);

        logger.debug("抛帐结束loanId:{}", amLoanMainInfo.getLoanId());
        return castWaiveAccountBean;
    }

    /**
     * 抛账  抛出利息累计账户
     *
     * @param amRepaymentPlanInfo 当期还款计划
     * @param accrualBaseAmount   计息基础金额
     * @return
     */
    @Override
    public AmInterestAccrualInfo castInterestAccrualAccount(AmRepaymentPlanInfo amRepaymentPlanInfo, AmLoanAccountInfo amLoanAccountInfo,
                                                            AmLoanMainInfo amLoanMainInfo, BigDecimal accrualBaseAmount, DelqParamBean delqParamBean, BigDecimal maxIntrAmt) throws TxnBizException {
        if (BigDecimal.ZERO.compareTo(maxIntrAmt) >= 0) {
            return null;
        }

        AmInterestAccrualInfo amInterestAccrualInfo = new AmInterestAccrualInfo();
        BeanMapping.copy(amLoanMainInfo, amInterestAccrualInfo);
        try {
            amInterestAccrualInfo.setId(segmentService.getId(TransBizConstant.AM_INTEREST_ACCRUAL_INFO_ID));//id
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnBizException(TxnRespCode.ERROR.getUserTips());
        }
        amInterestAccrualInfo.setAccountId(getAccountId(TransBizConstant.INTEREST_ACCRUAL_TYPE_66,
                amLoanMainInfo.getTenantId(), amLoanMainInfo.getCustomerId()));//账户ID
        amInterestAccrualInfo.setBillingTenor(amRepaymentPlanInfo.getBillingTenor());
        amInterestAccrualInfo.setPaymentDueDate(amRepaymentPlanInfo.getPaymentDueDate());
        amInterestAccrualInfo.setAccountStatus(TransBizConstant.INTEREST_ACCRUAL_STATUS_1);//状态
        amInterestAccrualInfo.setAccountType(TransBizConstant.INTEREST_ACCRUAL_TYPE_66);//类型 利息累计账户
        amInterestAccrualInfo.setAccrualBaseAmount(accrualBaseAmount);//计息金额
        amInterestAccrualInfo.setAccrualStartDate(amRepaymentPlanInfo.getIntrStartDate());//交易起息日期
        amInterestAccrualInfo.setAccrualTotalAccruInterest(BigDecimal.ZERO);//已累计总利息
        amInterestAccrualInfo.setAccrualTotalAccruDays(TransBizConstant.ZERO);//已累计总天数
        amInterestAccrualInfo.setAccrualDailyRate(amRepaymentPlanInfo.getActualDailyRate());//实际日利率
        amInterestAccrualInfo.setAccrualNewFromDate(DateUtils.addDay(amRepaymentPlanInfo.getIntrStartDate(), -1));//累计利息开始日期
        amInterestAccrualInfo.setStopAccrualFlag(TransBizConstant.STOP_ACCRU_FLAG_0);//停止累计息标志	0 = 正常计息  1 = 停止计息
        amInterestAccrualInfo.setMaxInterest(maxIntrAmt);//最大利息金额
        amInterestAccrualInfo.setProfitShared(TransBizConstant.NO_FLAG);//是否已经分润	0 = 未分润 1 = 已分润  默认为0，未分润	初始固定值：0
        amInterestAccrualInfo.setBalTransferFlag(TransBizConstant.NO_FLAG);//债权转移标识
        amInterestAccrualInfo.setCompensatoryFlag(TransBizConstant.NO_FLAG);//代偿标识
        amInterestAccrualInfo.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);//	记录版本号	初始固定值：1
        amInterestAccrualInfo.setUpdateBy(TransBizConstant.SYS_OPRATE);
        amInterestAccrualInfo.setTaxAmt(BigDecimal.ZERO);
        amInterestAccrualInfo.setLiabilityFlag(amRepaymentPlanInfo.getLiabilityFlag());
        amInterestAccrualInfo.setProvisionalAccrualInterest(BigDecimal.ZERO);
        amInterestAccrualInfo.setProvisionalTaxAmt(BigDecimal.ZERO);
        amInterestAccrualInfo.setCreateTime(null);
        amInterestAccrualInfo.setUpdateTime(null);

        amInterestAccrualInfo.setAccountingPhase(TransBizConstant.ACCOUNTING_PHASE_0);//会计状态
        //应计/非应计
        this.transNonAccrualsFlag(delqParamBean, amInterestAccrualInfo, amLoanAccountInfo);
        //五级分类
        amInterestAccrualInfo.setLoanClassify(amLoanAccountInfo.getLoanClassify());

        if (TransBizConstant.NON_ACCRUALS_FLA_0.equals(amInterestAccrualInfo.getNonAccrualsFlag())) {
            amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_INST_INTR_ACCU);
        } else {
            amInterestAccrualInfo.setTxnCode(TransBizConstant.TXN_CODE_INST_INTR_NONACCRUAL_ACCU);
        }
        return amInterestAccrualInfo;
    }
}
